package com.yf.ability.business.sms.service.impl;


import com.alibaba.fastjson.JSON;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;

import com.yf.ability.business.sms.config.SmsConfig;
import com.yf.ability.business.sms.config.provider.SmsAliyunConfig;
import com.yf.ability.business.sms.service.SmsService;
import com.yf.ability.system.captcha.service.CaptchaService;
import com.yf.ability.system.redis.service.RedisService;
import com.yf.framework.exception.ServiceException;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 短信发送业务类
 * @author bool
 * @date 2020-02-17 09:52
 */
@Service
public class SmsServiceImpl implements SmsService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private CaptchaService captchaService;

    @Autowired
    private SmsConfig smsConfig;



    /**
     * 发送成功代码
     */
    private static final String SUCCESS_CODE = "OK";

    /**
     * 300秒有效期
     */
    private static final Long SMS_EXPIRY = 300L;

    /**
     * 验证码缓存前缀
     */
    private static final String SMS_PREFIX = "mobile:sms:";

    @Override
    public boolean sendSms(String mobile,
                           String captchaKey,
                           String captchaValue) {

        boolean check = captchaService.checkCaptcha(captchaKey, captchaValue);

        if(!check){
            throw new ServiceException("必须输入正确的图形验证码才能发送！");
        }

        // 产生短信验证码
        String sms = RandomStringUtils.randomNumeric(6);

        // 发送短信
        Map<String,Object> params = new HashMap<>(16);
        params.put("code", sms);
        boolean result = sendSms(mobile, params);

        // 保存到缓存中
        if(result){
            redisService.set(appendKey(mobile), sms, SMS_EXPIRY);
        }

        return result;

    }

    @Override
    public boolean checkSms(String mobile, String sms) {
        String content = redisService.getString(appendKey(mobile));
        boolean check = content!=null && content.equals(sms);
        return check;
    }


    /**
     * 组合KEY
     * @param key
     * @return
     */
    private String appendKey(String key){
        return new StringBuffer(SMS_PREFIX).append(key).toString();
    }


    /**
     * 通用发送短信
     * @param mobiles
     * @param params
     * @return
     * @throws Exception
     */
    public boolean sendSms(String mobiles, Map<String,Object> params) {


        SmsAliyunConfig conf = smsConfig.getAliConfig();

        System.out.println("+++++短信配置："+JSON.toJSONString(conf));

        if(conf == null || StringUtils.isBlank(conf.getAccessKeyId()) || StringUtils.isBlank(conf.getAccessKeySecret())){
            throw new ServiceException("短信配置错误，请联系管理员！");
        }

        Config config = new Config()
                .setAccessKeyId(conf.getAccessKeyId())
                .setAccessKeySecret(conf.getAccessKeySecret());
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        Client client;
        try {
            client = new Client(config);
            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(mobiles);
            request.setSignName(conf.getSign());
            request.setTemplateCode(conf.getTmpl());
            request.setTemplateParam(JSON.toJSONString(params));
            SendSmsResponse response = client.sendSms(request);

            String code = response.body.code;

            // 响应码
            if(SUCCESS_CODE.equals(code)) {
                return true;
            }

        } catch (Exception e) {
            throw new ServiceException("短信发送失败，请联系管理员！");
        }

        return false;
    }
}
